#include "../src/parser/sql_parser.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

// Test helper functions
static void print_test_header(const char* test_name);
static void print_test_result(const char* test_name, bool passed);

static void print_test_header(const char* test_name) {
    printf("\n=== %s ===\n", test_name);
}

static void print_test_result(const char* test_name, bool passed) {
    printf("%s: %s\n", test_name, passed ? "PASSED" : "FAILED");
}

// Test CREATE VIEW parsing
static bool test_create_view_basic(void) {
    print_test_header("Testing Basic CREATE VIEW Parsing");
    
    const char* sql = "CREATE VIEW my_view AS SELECT name, age FROM users WHERE age > 18";
    printf("Parsing SQL: %s\n", sql);
    
    parser_t* parser = parser_create(sql);
    if (!parser) {
        printf("Failed to create parser\n");
        return false;
    }
    
    statement_t* stmt = parser_parse_statement(parser);
    bool success = false;
    
    if (parser_has_error(parser)) {
        printf("Parser error: %s\n", parser_get_error(parser));
    } else if (stmt && stmt->type == STMT_CREATE_VIEW) {
        printf("Successfully parsed CREATE VIEW statement\n");
        printf("View name: %s\n", stmt->data.create_view.view_name);
        printf("OR REPLACE: %s\n", stmt->data.create_view.or_replace ? "true" : "false");
        
        if (stmt->data.create_view.view_name && 
            strcmp(stmt->data.create_view.view_name, "my_view") == 0) {
            success = true;
        } else {
            printf("View name mismatch\n");
        }
        
        statement_destroy(stmt);
    } else {
        printf("Failed to parse statement or wrong statement type\n");
    }
    
    parser_destroy(parser);
    return success;
}

// Test CREATE OR REPLACE VIEW parsing
static bool test_create_or_replace_view(void) {
    print_test_header("Testing CREATE OR REPLACE VIEW Parsing");
    
    const char* sql = "CREATE OR REPLACE VIEW user_view AS SELECT * FROM users";
    printf("Parsing SQL: %s\n", sql);
    
    parser_t* parser = parser_create(sql);
    if (!parser) {
        printf("Failed to create parser\n");
        return false;
    }
    
    statement_t* stmt = parser_parse_statement(parser);
    bool success = false;
    
    if (parser_has_error(parser)) {
        printf("Parser error: %s\n", parser_get_error(parser));
    } else if (stmt && stmt->type == STMT_CREATE_VIEW) {
        printf("Successfully parsed CREATE OR REPLACE VIEW statement\n");
        printf("View name: %s\n", stmt->data.create_view.view_name);
        printf("OR REPLACE: %s\n", stmt->data.create_view.or_replace ? "true" : "false");
        
        if (stmt->data.create_view.or_replace) {
            success = true;
        } else {
            printf("OR REPLACE flag not set\n");
        }
        
        statement_destroy(stmt);
    } else {
        printf("Failed to parse statement or wrong statement type\n");
    }
    
    parser_destroy(parser);
    return success;
}

// Test CREATE VIEW with complex SELECT (without aliases for now)
static bool test_create_view_complex(void) {
    print_test_header("Testing CREATE VIEW with Complex SELECT");
    
    const char* sql = "CREATE VIEW dept_summary AS SELECT department, COUNT(*), AVG(salary) FROM employees WHERE status = 'active' GROUP BY department HAVING COUNT(*) > 5 ORDER BY department";
    printf("Parsing SQL: %s\n", sql);
    
    parser_t* parser = parser_create(sql);
    if (!parser) {
        printf("Failed to create parser\n");
        return false;
    }
    
    statement_t* stmt = parser_parse_statement(parser);
    bool success = false;
    
    if (parser_has_error(parser)) {
        printf("Parser error: %s\n", parser_get_error(parser));
    } else if (stmt && stmt->type == STMT_CREATE_VIEW) {
        printf("Successfully parsed complex CREATE VIEW statement\n");
        printf("View name: %s\n", stmt->data.create_view.view_name);
        
        bool has_select = stmt->data.create_view.select_list != NULL;
        bool has_from = stmt->data.create_view.from_list != NULL;
        bool has_where = stmt->data.create_view.where_clause != NULL;
        bool has_group_by = stmt->data.create_view.group_by != NULL;
        bool has_having = stmt->data.create_view.having != NULL;
        bool has_order_by = stmt->data.create_view.order_by != NULL;
        
        printf("View clauses found:\n");
        printf("  SELECT: %s\n", has_select ? "yes" : "no");
        printf("  FROM: %s\n", has_from ? "yes" : "no");
        printf("  WHERE: %s\n", has_where ? "yes" : "no");
        printf("  GROUP BY: %s\n", has_group_by ? "yes" : "no");
        printf("  HAVING: %s\n", has_having ? "yes" : "no");
        printf("  ORDER BY: %s\n", has_order_by ? "yes" : "no");
        
        success = has_select && has_from && has_where && has_group_by && has_having && has_order_by;
        
        statement_destroy(stmt);
    } else {
        printf("Failed to parse statement or wrong statement type\n");
    }
    
    parser_destroy(parser);
    return success;
}

// Test DROP VIEW parsing
static bool test_drop_view_basic(void) {
    print_test_header("Testing Basic DROP VIEW Parsing");
    
    const char* sql = "DROP VIEW my_view";
    printf("Parsing SQL: %s\n", sql);
    
    parser_t* parser = parser_create(sql);
    if (!parser) {
        printf("Failed to create parser\n");
        return false;
    }
    
    statement_t* stmt = parser_parse_statement(parser);
    bool success = false;
    
    if (parser_has_error(parser)) {
        printf("Parser error: %s\n", parser_get_error(parser));
    } else if (stmt && stmt->type == STMT_DROP_VIEW) {
        printf("Successfully parsed DROP VIEW statement\n");
        printf("View name: %s\n", stmt->data.drop_view.view_name);
        printf("IF EXISTS: %s\n", stmt->data.drop_view.if_exists ? "true" : "false");
        printf("CASCADE: %s\n", stmt->data.drop_view.cascade ? "true" : "false");
        
        if (stmt->data.drop_view.view_name && 
            strcmp(stmt->data.drop_view.view_name, "my_view") == 0) {
            success = true;
        } else {
            printf("View name mismatch\n");
        }
        
        statement_destroy(stmt);
    } else {
        printf("Failed to parse statement or wrong statement type\n");
    }
    
    parser_destroy(parser);
    return success;
}

// Test DROP VIEW IF EXISTS parsing
static bool test_drop_view_if_exists(void) {
    print_test_header("Testing DROP VIEW IF EXISTS Parsing");
    
    const char* sql = "DROP VIEW IF EXISTS user_view CASCADE";
    printf("Parsing SQL: %s\n", sql);
    
    parser_t* parser = parser_create(sql);
    if (!parser) {
        printf("Failed to create parser\n");
        return false;
    }
    
    statement_t* stmt = parser_parse_statement(parser);
    bool success = false;
    
    if (parser_has_error(parser)) {
        printf("Parser error: %s\n", parser_get_error(parser));
    } else if (stmt && stmt->type == STMT_DROP_VIEW) {
        printf("Successfully parsed DROP VIEW IF EXISTS statement\n");
        printf("View name: %s\n", stmt->data.drop_view.view_name);
        printf("IF EXISTS: %s\n", stmt->data.drop_view.if_exists ? "true" : "false");
        printf("CASCADE: %s\n", stmt->data.drop_view.cascade ? "true" : "false");
        
        if (stmt->data.drop_view.if_exists && stmt->data.drop_view.cascade) {
            success = true;
        } else {
            printf("IF EXISTS or CASCADE flags not set correctly\n");
        }
        
        statement_destroy(stmt);
    } else {
        printf("Failed to parse statement or wrong statement type\n");
    }
    
    parser_destroy(parser);
    return success;
}

// Test invalid VIEW syntax
static bool test_invalid_view_syntax(void) {
    print_test_header("Testing Invalid VIEW Syntax (should fail)");
    
    const char* sql = "CREATE VIEW my_view"; // Missing AS SELECT
    printf("Parsing SQL: %s\n", sql);
    
    parser_t* parser = parser_create(sql);
    if (!parser) {
        printf("Failed to create parser\n");
        return false;
    }
    
    statement_t* stmt = parser_parse_statement(parser);
    bool success = false;
    
    if (parser_has_error(parser)) {
        printf("Expected parser error: %s\n", parser_get_error(parser));
        success = true;  // This should fail, so error is expected
    } else if (stmt) {
        printf("Unexpected success - invalid syntax should fail\n");
        statement_destroy(stmt);
    }
    
    parser_destroy(parser);
    return success;
}

int main() {
    printf("VIEW Parsing Test Suite\n");
    printf("=======================\n");
    
    int passed = 0;
    int total = 0;
    
    // Run all tests
    struct {
        const char* name;
        bool (*test_func)(void);
    } tests[] = {
        {"Basic CREATE VIEW", test_create_view_basic},
        {"CREATE OR REPLACE VIEW", test_create_or_replace_view},
        {"Complex CREATE VIEW", test_create_view_complex},
        {"Basic DROP VIEW", test_drop_view_basic},
        {"DROP VIEW IF EXISTS", test_drop_view_if_exists},
        {"Invalid VIEW Syntax", test_invalid_view_syntax},
        {NULL, NULL}
    };
    
    for (int i = 0; tests[i].name != NULL; i++) {
        total++;
        bool result = tests[i].test_func();
        if (result) {
            passed++;
        }
        print_test_result(tests[i].name, result);
    }
    
    printf("\n=== Test Summary ===\n");
    printf("Passed: %d/%d\n", passed, total);
    printf("Success rate: %.1f%%\n", (double)passed / total * 100.0);
    
    return (passed == total) ? 0 : 1;
}